package me.moscrop.RootCommand.commands;

import java.io.File;
import java.util.List;
import java.util.logging.Logger;

import me.moscrop.RootCommand.utilities.Utility;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.util.config.Configuration;

public class Warp {
	
	private File file;
	private Configuration config;

	
	public Warp(String pluginDir)
	{
		file = new File(pluginDir + File.separator + "warps.yml");
			
		config = new Configuration(file);
        config.load();
        checkConfig();

        new File(pluginDir).mkdir();

        if(!file.exists()){
            try {
                file.createNewFile();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
	}
	
	public void loadConfig()
	{
        config.load();
        checkConfig();
	}
	
	private void checkConfig()
	{
		List<String> selectedKit = config.getKeys();
		String warp;
		Logger log = Logger.getLogger("Minecraft");
		
		if(selectedKit.size() == 0)
		{
			return;
		}
		
		for(int i = 0; i < selectedKit.size(); i ++)
		{
			warp = selectedKit.get(i);
			Object temp;

			temp = config.getProperty(warp + ".Visibility");
			if(temp != null)
			{
				if(!(((String) temp).contentEquals("public") || ((String) temp).contentEquals("private")))
				{
					log.warning("WARNING, warp " + warp + "'s visibility is corrupt, repairing...");
					config.setProperty(warp + ".Visibility", "public");
					log.warning("Warp " + warp + "'s visibility has been set to public.");
				}
			}
			
			String[] toCheck = {"Yaw","Pitch", "X", "Y", "Z"};
			
			
			for(String stat : toCheck )
			{
				if(Utility.isNum(config.getProperty(warp + ".Location." + stat)))
				{
					log.warning("WARNING, Property " + stat +" of warp " + warp + " is incorrect, setting to 0.");
					config.setProperty(warp + ".Location." + stat, 0);
				}
			}
			
			config.save();
			
		}
	}

	public boolean onCommand(CommandSender sender, String[] args)
	{
		
	
		
		//give instructions
		if(args.length == 0 || (args.length == 1 && (args[0].contentEquals(""))))
		{
			displayHelp(sender);
			return true;
		}
		

		if(args[0].contentEquals("add"))
		{
			if(args.length > 2)
			{
				addWarp(sender, args[1], args[2]);
				return true;
			} if(args.length > 1)
			{
				addWarp(sender, args[1], "public");
				return true;
			}else{
				sender.sendMessage(ChatColor.RED + "Warning, your missing an argument.");
				return true;
			}
		}
		
		if(args[0].contentEquals("list"))
		{
			listWarps(sender);
			return true;
		}
		
		if(args[0].contentEquals("remove"))
		{
			if(args.length > 1)
			{
				removeWarp(sender, args[1]);
				return true;
			}else{
				sender.sendMessage(ChatColor.RED + "Warning, your missing an argument.");
				return true;
			}
		}
		
		if(args[0].contentEquals("set"))
		{
			if(args.length > 1)
			{
				setWarp(sender, args[1],args[2]);
				return true;
			}else{
				sender.sendMessage(ChatColor.RED + "Warning, your missing an argument.");
				return true;
			}
		}

	
		if(exists(args[0]))
		{
			sendToWarp(sender, args[0]);
			return true;
		}
		
		sender.sendMessage(ChatColor.RED + "Error: arguemnt '" + args[0] + "' is not a warp point or a command.");
		//displayHelp(sender);
		
		return true;
	}

	private void sendToWarp(CommandSender sender, String warpName)
	{
		//exit if console
		if(Utility.isConsole(sender))
			return;
		
		
		if(exists(warpName))
		{
			if(((String) config.getProperty(warpName + ".Visibility")).contentEquals("private"))
			{
				if(!(((String) config.getProperty(warpName + ".Owner")).contentEquals(sender.getName())))
				{
					sender.sendMessage(ChatColor.RED + "Sorry, you can't goto a warp which doesnt belong to you.");
					return;
				}
			}
			
			String dir = warpName + ".Location.";
			World world = Bukkit.getWorld((String) config.getProperty(dir + "World"));
			
			if(world == null)
			{
				sender.sendMessage(ChatColor.RED + "Warning, the world this warp was set it does not exist.");
				sender.sendMessage(ChatColor.RED + "Removal of warp " + warpName + " is recommended.");
				return;
			}
			
			//Make/setup location var
			Location newLoci = new Location(world,0,0,0);
			newLoci.setX((Double) config.getProperty(dir + "X"));
			newLoci.setY((Double) config.getProperty(dir + "Y"));
			newLoci.setZ((Double) config.getProperty(dir + "Z"));
			newLoci.setYaw(((Double) config.getProperty(dir + "Yaw")).floatValue());
			newLoci.setPitch(((Double) config.getProperty(dir + "Pitch")).floatValue());

			
			//Teleport the user the the location
			((Player) sender).teleport(Utility.getSafeLocationAt(newLoci));
			sender.sendMessage(ChatColor.GREEN + "Welcome to " + warpName +".");
			
		}else{
			//Error that the war does not exist
			sender.sendMessage(ChatColor.RED + "Sorry, that warp does not exist.");
		}
	}

	private void addWarp(CommandSender sender, String warpName, String visibility) {
		
		if(Utility.isConsole(sender))
			return;
		
		if(visibility != "")
		{
			if(!(visibility.contentEquals("public") || visibility.contentEquals("private")))
			{
				sender.sendMessage(ChatColor.RED + "Warning, " + visibility +" is not a valid mode, setting to public.");
				visibility = "public";
			}
		}
			
		warpName = warpName.toLowerCase();
		if(exists(warpName))
		{
			sender.sendMessage(ChatColor.RED + "Sorry, " + warpName + " already exists.");
			return;
		}else{
			Location loci = ((Player) sender).getLocation();
			config.setProperty(warpName + ".Location.World", loci.getWorld().getName());
			config.setProperty(warpName + ".Location.X", loci.getX());
			config.setProperty(warpName + ".Location.Y", loci.getY());
			config.setProperty(warpName + ".Location.Z", loci.getZ());
			config.setProperty(warpName + ".Location.Yaw", loci.getYaw());
			config.setProperty(warpName + ".Location.Pitch", loci.getPitch());
			config.setProperty(warpName + ".Visibility", "public");
			config.setProperty(warpName + ".Owner", ((Player) sender).getName());
		}
		
		sender.sendMessage(ChatColor.GREEN + "Warp " + warpName + " added.");
		config.save();
	}
	
	private void setWarp(CommandSender sender, String warpName, String visibility) {

		warpName = warpName.toLowerCase();
		
		if(!(visibility.contentEquals("public") || visibility.contentEquals("private")))
		{
			sender.sendMessage(ChatColor.RED + "Error, options are public or private, not " + visibility +".");
			return;
		}
		
		if(exists(warpName))
		{
			
			if(!(((String) config.getProperty(warpName + ".Owner")).contentEquals(sender.getName())))
			{
				sender.sendMessage(ChatColor.RED + "Sorry, you can't edit a warp which doesnt belong to you.");
				return;
			}
			
			config.setProperty(warpName + ".Visibility", visibility);
			sender.sendMessage(ChatColor.GREEN + "Warp " + warpName + " status set to " + visibility + ".");
			config.save();
			return;
		}else{
			sender.sendMessage(ChatColor.RED + "Sorry, " + warpName + " doesnt exist.");
			return;
		}
		
	}
	
	private void listWarps(CommandSender sender)
	{
		List<String> selectedKit = config.getKeys();
		String warp;
		
		if(selectedKit.size() == 0)
		{
			sender.sendMessage(ChatColor.RED + "No warps.");
			return;
		}
		
		sender.sendMessage(ChatColor.RED + "Warps");
		sender.sendMessage(ChatColor.RED + "------");
		for(int i = 0; i < selectedKit.size(); i ++)
		{
			warp = selectedKit.get(i);
			if(((String) config.getProperty(warp + ".Visibility")).contentEquals("public"))
			{
				sender.sendMessage(ChatColor.RED + warp + " - public");
				continue;
			}else{
				if(config.getProperty(warp + ".Owner") == sender.getName())
				{
					sender.sendMessage(ChatColor.RED + warp + " - private");
					continue;
				}
			}
			
		}
		
	}

	private void removeWarp(CommandSender sender, String warpName)
	{
		warpName = warpName.toLowerCase();
		if(exists(warpName))
		{
			if(!(((String) config.getProperty(warpName + ".Owner")).contentEquals(sender.getName())))
			{
				sender.sendMessage(ChatColor.RED + "Sorry, you can't remove a warp which doesnt belong to you.");
				return;
			}
			
			config.removeProperty(warpName);
			sender.sendMessage(ChatColor.GREEN + "Warp " + warpName + " removed.");
			config.save();
		}else{
			sender.sendMessage(ChatColor.RED + "Error: No warp by the name of " + warpName + ".");
			return;
		}
		
	}

	private void displayHelp(CommandSender sender)
	{
		sender.sendMessage(ChatColor.RED + "Usage: /warp add <warp> [private/public]");
		sender.sendMessage(ChatColor.RED + "Usage: /warp list");
		sender.sendMessage(ChatColor.RED + "Usage: /warp remove <warp name>");
		sender.sendMessage(ChatColor.RED + "Usage: /warp set <warp> <private/public>");
		sender.sendMessage(ChatColor.RED + "Usage: /warp <warp location>");
		
	}
	
	private boolean exists(String warpPoint)
	{
		Object result = config.getProperty(warpPoint);
		if(result == null)
		{
			return false;
		}
		return true;
	}
	
}
